package pers.ree.demo.concurrent;

public class ThreadGroupDemo {
    public static void main(String[] args) {
        ThreadGroup tg = new ThreadGroup("testThreadGroup");
        testGroupDaemon(tg);

//        Thread t1 = new Thread(tg, () -> {
//            while(!Thread.currentThread().isInterrupted()) {
//                print();
//            }
//        });
//        t1.start();
//
//        Thread t2 = new Thread(tg, () -> {
//            while (true) {
//                print();
//                try {
//                    Thread.sleep(100L);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                    break;
//                }
//            }
//        });
//        t2.start();
//
//        System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " maxPriority: " + tg.getMaxPriority());
//
//        try {
//            Thread.sleep(1000L);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//
//        System.out.println("first sleep");
    }

    private static void print() {
        System.out.println(Thread.currentThread().getName() + " running");
    }

    private static void testGroupDaemon(ThreadGroup tg) {
        // 线程组设置daemon=true时，改变的只是group的daemon值，不会改变组内的线程的daemon值，除非遍历线程逐一设置daemon，
        // 线程组设置daemon=true后，理论上其中的所有线程都执行完以后，线程组会自动destroy，
        // 但是实际测试中，什么时候会触发group的destroy并不固定，有时候线程都结束后很快就触发，少数时候一直没有触发，
        // 所以实际开发中，最好不要依赖tg.isDestroyed的值进行某些操作
        tg.setDaemon(true);

        Runnable runnable = () -> {
            for (int i=0; i<100000; i++) {
                print();
            }
        };

        Thread t1 = new Thread(tg, runnable);
        t1.start();

        Thread t2 = new Thread(tg, runnable);
        t2.start();

        System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " maxPriority: " + tg.getMaxPriority());

        System.out.println("group isDaemon: " + tg.isDaemon() + ", t1 isDaemon: " + t1.isDaemon() + ", t2 isDaemon: " + t2.isDaemon());

        while(!tg.isDestroyed()) {
            System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " isDestroyed: " + tg.isDestroyed());
        }
        System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " isDestroyed: " + tg.isDestroyed());
    }

    private static void testInterrupt(ThreadGroup tg) {
        tg.interrupt();
        System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " maxPriority: " + tg.getMaxPriority());
    }

    private static void testDestroy(ThreadGroup tg, Thread t1, Thread t2) {
        // 调用destroy方法前，线程组不能有还在运行的线程
        t1.interrupt();
        t2.interrupt();
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("after second sleep and before destroy, " + tg.getName() + " activeCount: " + tg.activeCount() + " maxPriority: " + tg.getMaxPriority());
        tg.destroy();
        System.out.println(tg.getName() + " activeCount: " + tg.activeCount() + " maxPriority: " + tg.getMaxPriority());


    }

    /**
     * 未验证的功能点
     */
    private static void testTodo() {
//        tg.suspend();
//        tg.resume(); // todo
        // todo uncaughtException(Thread t, Throwable e)
    }
}
